"""
阿里百炼知识库服务模块
处理与阿里百炼云知识库的交互，包括检索和管理功能
"""

import logging
from typing import List

from alibabacloud_bailian20231229 import models as bailian_20231229_models
from alibabacloud_bailian20231229.client import Client as bailian20231229Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models

from backend.config.constants import Config

logger = logging.getLogger(__name__)


class BailianKnowledgeService:
    """阿里百炼知识库服务类"""
    
    def __init__(self):
        self.access_key_id = Config.ALIBABA_CLOUD_ACCESS_KEY_ID
        self.access_key_secret = Config.ALIBABA_CLOUD_ACCESS_KEY_SECRET
        self.workspace_id = Config.WORKSPACE_ID
        self.knowledge_base_id = Config.BAILIAN_KNOWLEDGE_BASE_ID
        self.client = None
        self._initialize()
    
    def _initialize(self):
        """初始化阿里百炼客户端"""
        try:
            if not self.access_key_id or not self.access_key_secret:
                logger.warning("未设置阿里云访问密钥，无法初始化阿里百炼知识库服务")
                return
            
            if not self.workspace_id or not self.knowledge_base_id:
                logger.warning("未设置阿里百炼工作空间ID或知识库ID，无法初始化阿里百炼知识库服务")
                return
            
            # 创建配置
            config = open_api_models.Config(
                access_key_id=self.access_key_id,
                access_key_secret=self.access_key_secret
            )
            # 设置接入地址
            config.endpoint = 'bailian.cn-beijing.aliyuncs.com'
            
            # 创建客户端
            self.client = bailian20231229Client(config)
            logger.info("成功初始化阿里百炼知识库服务")
            
        except Exception as e:
            logger.error(f"初始化阿里百炼知识库服务失败: {e}")
            self.client = None
    
    def retrieve_knowledge(self, query: str) -> List[str]:
        """从阿里百炼知识库中检索相关知识"""
        if not self.client or not self.workspace_id or not self.knowledge_base_id:
            logger.warning("阿里百炼知识库服务未正确初始化")
            return []
        
        try:
            # 构造检索请求
            headers = {}
            # 根据官方示例，只传递index_id和query参数
            retrieve_request = bailian_20231229_models.RetrieveRequest(
                index_id=self.knowledge_base_id,
                query=query
            )
            runtime = util_models.RuntimeOptions()
            
            # 执行检索
            response = self.client.retrieve_with_options(
                self.workspace_id, 
                retrieve_request, 
                headers, 
                runtime
            )
            
            # 添加详细的日志信息
            logger.debug(f"阿里百炼知识库检索响应: {response}")
            
            # 解析结果
            if response.body and response.body.data:
                # 检查response.body.data的类型
                logger.debug(f"响应数据类型: {type(response.body.data)}")
                logger.debug(f"响应数据内容: {response.body.data}")
                
                # 提取检索到的文档内容
                documents = []
                
                # 根据调试结果，response.body.data是一个RetrieveResponseBodyData对象，包含nodes属性（小写）
                # 注意：属性名是'nodes'（小写），不是'Nodes'（大写）
                if hasattr(response.body.data, 'nodes') and response.body.data.nodes:
                    logger.debug(f"找到 {len(response.body.data.nodes)} 个节点")
                    for node in response.body.data.nodes:
                        # 每个节点应该有text属性（小写），包含检索到的文本内容
                        # 从日志中可以看到节点有text属性而不是Text属性
                        if hasattr(node, 'text') and node.text:
                            documents.append(node.text)
                            logger.debug(f"添加文档片段: {node.text[:100]}...")
                        # 也可以检查Text属性（如果存在）
                        elif hasattr(node, 'Text') and node.Text:
                            documents.append(node.Text)
                            logger.debug(f"添加文档片段: {node.Text[:100]}...")
                        # 也可以检查content属性（如果存在）
                        elif hasattr(node, 'content') and node.content:
                            documents.append(node.content)
                            logger.debug(f"添加文档内容: {node.content[:100]}...")
                        else:
                            logger.debug(f"节点没有text、Text或content属性: {dir(node)}")
                else:
                    logger.warning("响应数据中没有nodes属性或nodes为空")
                    logger.debug(f"response.body.data属性: {dir(response.body.data) if response.body.data else 'None'}")
                
                logger.info(f"从阿里百炼知识库检索到 {len(documents)} 个相关文档")
                return documents
            else:
                logger.warning("阿里百炼知识库检索未返回有效数据")
                if response.body:
                    logger.debug(f"响应body内容: {response.body}")
                return []
                
        except Exception as e:
            logger.error(f"从阿里百炼知识库检索知识失败: {e}")
            import traceback
            logger.error(f"详细错误信息: {traceback.format_exc()}")
            return []
    
    def is_initialized(self) -> bool:
        """检查服务是否已初始化"""
        return self.client is not None and self.workspace_id is not None and self.knowledge_base_id is not None


# 全局阿里百炼知识库服务实例
bailian_knowledge_service = BailianKnowledgeService()